//https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=vue%20websocket%20%E5%BF%83%E8%B7%B3&fenlei=256&oq=vue%2520websocket&rsv_pq=d33fec3903adccf4&rsv_t=e2fapBAkGpls7HMV9Awm2lNXKIrkiRui8HVBiv%2FZoStz7537TvTl11%2B0nQQ&rqlang=cn&rsv_enter=1&rsv_dl=tb&rsv_btype=t&inputT=2898&rsv_sug3=16&rsv_sug1=14&rsv_sug7=100&rsv_sug2=0&rsv_sug4=3039
https://blog.csdn.net/wangjiecsdn/article/details/125318796

//https://worktile.com/kb/p/3627257
//========================== 通信处理，参考https://yq.aliyun.com/articles/636357 ===============================//
var lockReconnect = false; //避免websocket重复连接
var websocket = null;

//心跳检测
var heartCheck = {
	timeout : 5 * 1000, //9分钟发一次心跳 540
	timeoutObj : null,
	serverTimeoutObj : null,
	reset : function() {
		clearTimeout(this.timeoutObj);
		clearTimeout(this.serverTimeoutObj);
		return this;
	},
	start : function() {
		console.log("lockReconnect = " + lockReconnect);
		var self = this;
		this.timeoutObj = setTimeout(function() {
			//这里发送一个心跳，后端收到后，返回一个心跳消息，
			//onmessage拿到返回的心跳就说明连接正常
			websocket.send("ping");
			appendMessage("发送ping");
			self.serverTimeoutObj = setTimeout(function() {
				//如果超过一定时间还没重置，说明后端主动断开了
				//如果onclose会执行reconnect，我们执行websocket.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
				websocket.close();
			}, self.timeout)
		}, this.timeout)
	}
}

function createWebSocket(url) {
	appendMessage(`正在连接到${url}`);
	try {
		if ('WebSocket' in window) {
			websocket = new WebSocket(url);
		} else if ('MozWebSocket' in window) {
			websocket = new MozWebSocket(url);
		} else {
			alert("您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器，请勿使用IE10以下浏览器，360浏览器请使用极速模式，不要使用兼容模式！");
		}
		initEventHandle();
	} catch (e) {
		reconnect(url);
		console.log(e);
	}
}

// 监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
window.onbeforeunload = function() {
	websocket.close();
}
function reconnect(url) {
	console.log("reconnect，lockReconnect = " + lockReconnect);
	if (lockReconnect) return;
	lockReconnect = true;
	setTimeout(function() { //没连接上会一直重连，设置延迟避免请求过多
		createWebSocket(url);
		lockReconnect = false;
	}, 2000);
}

//将消息显示在网页上
function appendMessage(message) {
	console.log(`${new Date().toLocaleString()}：: ${message}`);
}

//关闭连接
function closeWebSocket() {
	websocket.close();
}

// 把JSON发送到指定的客户端
function sendTo(toCid, json) {
	json.cid = cid;
	json.toCid = toCid;
	alert(json);
	return websocket.send(JSON.stringify(json));
}

// 初始化处理
function initEventHandle() {
	websocket.onclose = function() {
		appendMessage(`连接关闭!` + "lockReconnect = " + lockReconnect);
		reconnect(wsUrl);
	};
	websocket.onerror = function() {
		console.log("lockReconnect = " + lockReconnect);
		reconnect(wsUrl);
		appendMessage("WebSocket连接错误!");
	};
	websocket.onopen = function() {
		heartCheck.reset().start(); //心跳检测重置
		appendMessage(`${new Date().toLocaleString()}: 连接建立成功！wsUrl = ${wsUrl}，cid = ${cid}`);
		//其它页面可以自行编写onopenHandler()方法，但基本上没必要
		//onopenHandler();
	};
	websocket.onmessage = function(event) {
		//公共操作开始
		appendMessage(`收到消息：${event.data}` + "，lockReconnect = " + lockReconnect);
		//onmessageHandler()用于其它客户端接着处理event.data
		//onmessageHandler(event.data);
		//如果获取到消息，心跳检测重置，因为拿到任何消息都说明当前连接是正常的
		heartCheck.reset().start();
	};
}

